/*-------------------------------------------------------------------------
 *
 * pgtime.h
 *	  PostgreSQL 内部时区库
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *	  src/include/pgtime.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef _PGTIME_H
#define _PGTIME_H


/*
 * 该库的API通常类似于相应的C库函数，除了我们使用 pg_time_t，后者（我们希望）是
 * 64位宽，并且绝对是有符号的而不是无符号的。
 */

typedef int64 pg_time_t;

/*
 * 表示拆分时间戳的数据结构。
 *
 * 注意：IANA时区库（src/timezone/）遵循POSIX
 * 约定，即tm_mon从0开始计数，tm_year相对于1900。
 * 然而，Postgres的日期时间函数通常将tm_mon视为从1开始计数，
 * tm_year则相对于公元前1年。 在从一个代码域移动到另一个代码域时，请务必做出适当的调整。
 */
struct pg_tm
{
	int			tm_sec;
	int			tm_min;
	int			tm_hour;
	int			tm_mday;
	int			tm_mon;			/* 详见上文 */
	int			tm_year;		/* 详见上文 */
	int			tm_wday;
	int			tm_yday;
	int			tm_isdst;
	long int	tm_gmtoff;
	const char *tm_zone;
};

/* 这些结构在时区库外是不可见的 */
typedef struct pg_tz pg_tz;
typedef struct pg_tzenum pg_tzenum;

/* 时区名称的最大长度（不包括结尾的null） */
#define TZ_STRLEN_MAX 255

/* 这些函数在localtime.c中 */

extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz);
extern struct pg_tm *pg_gmtime(const pg_time_t *timep);
extern int	pg_next_dst_boundary(const pg_time_t *timep,
								 long int *before_gmtoff,
								 int *before_isdst,
								 pg_time_t *boundary,
								 long int *after_gmtoff,
								 int *after_isdst,
								 const pg_tz *tz);
extern bool pg_interpret_timezone_abbrev(const char *abbrev,
										 const pg_time_t *timep,
										 long int *gmtoff,
										 int *isdst,
										 const pg_tz *tz);
extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff);
extern const char *pg_get_timezone_name(pg_tz *tz);
extern bool pg_tz_acceptable(pg_tz *tz);

/* 这些函数在 strftime.c 中 */  

extern size_t pg_strftime(char *s, size_t max, const char *format,
						  const struct pg_tm *tm);

/* 这些函数和变量在 pgtz.c 中 */  

extern PGDLLIMPORT pg_tz *session_timezone;
extern PGDLLIMPORT pg_tz *log_timezone;

extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
extern pg_tz *pg_tzset_offset(long gmtoffset);

extern pg_tzenum *pg_tzenumerate_start(void);
extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir);
extern void pg_tzenumerate_end(pg_tzenum *dir);

#endif							/* _PGTIME_H */  
